/**
 * TiggerTcpServer类作为服务器角色，应该在接收到确认为请求数据包时向目标服务器发起连接
 */

import * as net from "net";
import { exit } from "process";
import { stringify } from "querystring";
import * as CommandHandler from "../command/command_handle";
import { control_err, control_log } from "../log/logger";
import Tunnel from "../tunnel/tunnel";
import Control from "../interfaces/control";

export default class TiggerTcpServer implements Control
{
    private registered_command: {cmd:string, cb:(args: number[]) => void}[];
    private server: Tunnel;

    constructor(options: net.ListenOptions){
        this.registered_command = new Array<{cmd:string, cb:(args: number[]) => void}>();
        this.server = new Tunnel(true, options);

        control_log("server listen " + options.port + " on " + options.host);
        
        // let client = net.createConnection(options, () => {
        //     console.log("与上游服务器连接成功");
        // });
        // client.on("error", (err) => {
        //     console.log("与上游服务器连接发生错误, 错误消息:" + err.message);
        // });
            //添加客户端(目前限制只有一个客户端)

        this.server.regBlockRecive((data: Buffer) => {
            for(let i in this.registered_command)
            {
                let cmd = this.registered_command[i];
                CommandHandler.default.resolveCommand(data, cmd.cmd, cmd.cb);
            }
        });
    }

    public getStatus():boolean {
        return this.server.getStatus();
    }

    /**
     * 注册连接成功事件
     * @param callback 连接成功触发的函数
     */
    public handleConnectionSuccess(callback:() => void): TiggerTcpServer
    {
        this.server.regConnected((socket: net.Socket) => {
            callback();

            socket.on("close", (had_error: boolean) => {
                    control_log("客户端断开连接")
            });

            socket.on("error", (err: NodeJS.ErrnoException) => {
                if(err.errno == -104)
                {
                    control_err("客户端发送了RST重置", err.errno);
                }
                control_err("客户端连接异常", -1);
            });
        });

        return this;
    }

    /**
     * 注册一个命令，当接受到此命令时，会触发一个函数
     * @param cmd 命令
     * @param cb 命令被调用时触发的函数
     * @returns this
     */
    public registerControlCommand(cmd: string, cb:(args: number[]) => void) {
        //控制命令注册
        if(cmd.length > 256)
        {
            control_err("尝试注册一个长度大于256的命令", -1);
        }
        this.registered_command.push({
            cmd: cmd,
            cb: cb
        });
        return this;
    }

    /**
     * 推送命令调用并附加参数到远端
     * @param cmd 命令
     * @param args 参数
     */
    public pushControlDataToRemote(cmd: string, args: number[]) {
        //因为只有一个客户端，钦定客户端id为0
        let id = 0;
        let data:Buffer = CommandHandler.default.packageCommand(cmd, args);
        if(!this.server.getStatus())
        {
            control_err("尝试在已关闭的控制线上读写", -1);
        }
        this.server.writeBlock(data);
    }
}

export function Server(options: net.ListenOptions) {
    return new TiggerTcpServer(options);
}
